﻿/*******************************************************************************
* file  : mem alloc.c
* creat : apleilx
* data  : 2017/03/02
*******************************************************************************/
#include "os_obj.h" // RTOS object definitions
#include "mem_alloc.h"
#include "str_ext.h"
#include "multi_malloc.h"

// 调试信息获取文件名
#if (DBG_EN + MALLOC_DBG_EN) > 1
#define file_name_site_get()           \
	int16_t site;                      \
	site = str_nsearch_ch(file, '\\'); \
	if (site < 0)                      \
		site = 0;                      \
	else                               \
		site++;
#else
#define file_name_site_get()
#endif

static uint64_t pool_mem[48 * 1024 / 8];
extern TX_THREAD *_tx_thread_current_ptr;

/*******************************************************************************
* @brief  os_mem_pool_creat.
* \param[in] none
* \retval: none
*******************************************************************************/
void os_mem_pool_creat(void)
{
	UINT os_err;

	// ccm poll creat
	os_err = tx_byte_pool_create(
		&os_obj.mem_pool,
		"mem pool",
		(void *)pool_mem,
		sizeof(pool_mem));

	os_obj.pid_mem = &os_obj.mem_pool;

	(void)os_err;

	os_api_exe_check();
}

/*******************************************************************************
* @brief  mem_malloc.
* \param[in] size
* \retval: point
*******************************************************************************/
#if (DBG_EN + MALLOC_DBG_EN) > 1
void *os_malloc(uint32_t size, char *file, int line)
#else
void *os_malloc(uint32_t size)
#endif
{
	UINT os_err, *ptr;

	size = ((size + 7) >> 3) << 3;

	os_err = tx_byte_allocate(
		os_obj.pid_mem,
		(VOID **)&ptr,
		size,
		ms_ticks(1000));

	(void)os_err;

	os_api_exe_check();

	if (os_err)
	{
		malloc_dbg_print("mem malloc fail : %s, %d\n", file, line);
		return 0;
	}
	else
	{
		file_name_site_get();

		malloc_dbg_print("mem malloc : 0x%08x size < %05d >  thread <%s> @ <%s --%d>\n",
						 (uint32_t)ptr,
						 size,
						 _tx_thread_current_ptr->tx_thread_name,
						 &file[site],
						 line);
	}

	return ptr;
}

/*******************************************************************************
* @brief  mem_calloc.
* \param[in] size
* \retval: point
*******************************************************************************/
#if (DBG_EN + MALLOC_DBG_EN) > 1
void *os_calloc(uint32_t items, uint32_t size, char *file, int line)
#else
void *os_calloc(uint32_t items, uint32_t size)
#endif
{
	UINT os_err, *ptr;

	size *= items;
	size = ((size + 7) >> 3) << 3;

	os_err = tx_byte_allocate(
		os_obj.pid_mem,
		(VOID **)&ptr,
		size,
		ms_ticks(1000));

	(void)os_err;

	os_api_exe_check();

	if (os_err)
	{
		malloc_dbg_print("mem calloc fail : %s, %d\n", file, line);
		return 0;
	}
	else
	{
		file_name_site_get();
		set_u32(ptr, 0, size >> 2);

		malloc_dbg_print("mem calloc : 0x%08x size < %05d >  thread <%s> @ <%s --%d>\n",
						 (uint32_t)ptr,
						 size,
						 _tx_thread_current_ptr->tx_thread_name,
						 &file[site],
						 line);
	}

	return ptr;
}

/*******************************************************************************
* @brief  mem_free.
* \param[in] pdat
* \retval: none
*******************************************************************************/
#if (DBG_EN + MALLOC_DBG_EN) > 1
void os_free(void *pdat, char *file, int line)
#else
void os_free(void *pdat)
#endif
{
	UINT os_err;
	file_name_site_get();

	if (!pdat)
	{
		malloc_dbg_print("mem free fail : %s, %d\n", file, line);
		return;
	}

	os_err = tx_byte_release(pdat);

	(void)os_err;

	os_api_exe_check();

	malloc_dbg_print("mem free  : 0x%08x   thread <%s> @ <%s --%d>\n",
					 (uint32_t)pdat,
					 _tx_thread_current_ptr->tx_thread_name,
					 &file[site],
					 line);
}

/*******************************************************************************
* @brief  std mem.
* \param[in] pdat
* \retval: none
*******************************************************************************/
void free(void *p)
{
	mem_free(p);
}

void *malloc(size_t size)
{
	return mem_malloc(size);
}

void *calloc(size_t num, size_t size)
{
	return mem_calloc(num, size);
}

void *realloc(void *p, size_t size)
{
	free(p);
	return malloc(size);
}
